<template>
  <el-dialog
    :title="`字节转换工具`"
    v-model="drawerVisible"
    :draggable="true"
    :overflow="true"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    top="30px"
    width="650px"
    :destroy-on-close="true"
  >
    <el-form :model="form" label-width="100px" label-position="left">
      <div class="byte-convert-form">
        <!-- 输入区域 -->
        <div class="input-section">
          <h3 class="section-title">
            <el-icon><Setting /></el-icon>
            文件大小转换
          </h3>

          <el-row :gutter="16">
            <el-col :span="12">
              <el-form-item label="输入数值:">
                <el-input-number
                  v-model="form.value"
                  :step="stepValue"
                  :precision="precision"
                  :min="0"
                  :max="maxValue"
                  controls-position="right"
                  style="width: 100%"
                  @change="handleConvert"
                  @input="handleConvert"
                  placeholder="请输入数值"
                />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="原始单位:">
                <el-select v-model="form.fromUnit" @change="handleConvert" style="width: 100%">
                  <el-option-group label="二进制单位 (1024)">
                    <el-option v-for="unit in binaryUnits" :key="unit.value" :label="unit.label" :value="unit.value">
                      <span style="float: left">{{ unit.label }}</span>
                      <span style="float: right; font-size: 13px; color: var(--el-text-color-secondary)">
                        {{ unit.description }}
                      </span>
                    </el-option>
                  </el-option-group>
                  <el-option-group label="十进制单位 (1000)">
                    <el-option v-for="unit in decimalUnits" :key="unit.value" :label="unit.label" :value="unit.value">
                      <span style="float: left">{{ unit.label }}</span>
                      <span style="float: right; font-size: 13px; color: var(--el-text-color-secondary)">
                        {{ unit.description }}
                      </span>
                    </el-option>
                  </el-option-group>
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>

          <el-row :gutter="16">
            <el-col :span="12">
              <el-form-item label="目标单位:">
                <el-select v-model="form.toUnit" @change="handleConvert" style="width: 100%">
                  <el-option-group label="二进制单位 (1024)">
                    <el-option v-for="unit in binaryUnits" :key="unit.value" :label="unit.label" :value="unit.value">
                      <span style="float: left">{{ unit.label }}</span>
                      <span style="float: right; font-size: 13px; color: var(--el-text-color-secondary)">
                        {{ unit.description }}
                      </span>
                    </el-option>
                  </el-option-group>
                  <el-option-group label="十进制单位 (1000)">
                    <el-option v-for="unit in decimalUnits" :key="unit.value" :label="unit.label" :value="unit.value">
                      <span style="float: left">{{ unit.label }}</span>
                      <span style="float: right; font-size: 13px; color: var(--el-text-color-secondary)">
                        {{ unit.description }}
                      </span>
                    </el-option>
                  </el-option-group>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="转换精度:">
                <el-select v-model="precision" @change="handleConvert" style="width: 100%">
                  <el-option label="整数" :value="0" />
                  <el-option label="1位小数" :value="1" />
                  <el-option label="2位小数" :value="2" />
                  <el-option label="3位小数" :value="3" />
                  <el-option label="6位小数" :value="6" />
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
        </div>

        <!-- 结果显示区域 -->
        <div class="result-section">
          <h3 class="section-title">
            <el-icon><View /></el-icon>
            转换结果
          </h3>

          <div class="result-display">
            <el-input v-model="result" readonly size="large" style="font-size: 18px; font-weight: 600; text-align: center">
              <template #append>
                <el-button @click="copyResult" :disabled="!result">
                  <el-icon><CopyDocument /></el-icon>
                  复制
                </el-button>
              </template>
            </el-input>
          </div>

          <!-- 详细转换信息 -->
          <div class="conversion-details" v-if="form.value > 0">
            <el-divider content-position="left">详细换算</el-divider>
            <div class="details-grid">
              <div class="detail-item" v-for="unit in allUnits" :key="unit.value">
                <span class="unit-label">{{ unit.label }}:</span>
                <span class="unit-value">{{ formatNumber(convertToUnit(unit.value)) }}</span>
              </div>
            </div>
          </div>
        </div>

        <!-- 快捷操作 -->
        <div class="quick-actions">
          <h3 class="section-title">
            <el-icon><Lightning /></el-icon>
            快捷转换
          </h3>
          <div class="quick-buttons">
            <el-button v-for="preset in quickPresets" :key="preset.label" size="small" @click="applyPreset(preset)">
              {{ preset.label }}
            </el-button>
          </div>
        </div>

        <!-- 使用说明 -->
        <div class="info-section">
          <el-alert title="使用说明" type="info" :closable="false" show-icon>
            <template #default>
              <ul class="info-list">
                <li><strong>二进制单位</strong>：以1024为进制，常用于计算机存储容量（KB、MB、GB等）</li>
                <li><strong>十进制单位</strong>：以1000为进制，常用于网络传输速度和磁盘制造商标注</li>
                <li><strong>精度设置</strong>：可调整小数位数，适应不同精度需求</li>
                <li><strong>快捷转换</strong>：点击预设按钮快速转换常见文件大小</li>
              </ul>
            </template>
          </el-alert>
        </div>
      </div>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="resetForm">重置</el-button>
        <el-button @click="drawerVisible = false">关闭</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts" name="ByteConverter">
import { ref, reactive, computed } from "vue";
import { ElMessage } from "element-plus";
import { Setting, View, CopyDocument, Lightning } from "@element-plus/icons-vue";

// 定义单位类型
interface Unit {
  label: string;
  value: string;
  bytes: number;
  description: string;
  type: "binary" | "decimal";
}

// 定义表单数据类型
interface FormState {
  value: number;
  fromUnit: string;
  toUnit: string;
}

// 定义快捷预设类型
interface QuickPreset {
  label: string;
  value: number;
  fromUnit: string;
  toUnit: string;
}

// 二进制单位 (1024进制)
const binaryUnits: Unit[] = [
  { label: "字节 (B)", value: "B", bytes: 1, description: "Byte", type: "binary" },
  { label: "千字节 (KB)", value: "KB", bytes: 1024, description: "KibiByte", type: "binary" },
  { label: "兆字节 (MB)", value: "MB", bytes: 1024 ** 2, description: "MebiByte", type: "binary" },
  { label: "吉字节 (GB)", value: "GB", bytes: 1024 ** 3, description: "GibiByte", type: "binary" },
  { label: "太字节 (TB)", value: "TB", bytes: 1024 ** 4, description: "TebiByte", type: "binary" },
  { label: "拍字节 (PB)", value: "PB", bytes: 1024 ** 5, description: "PebiByte", type: "binary" },
  { label: "艾字节 (EB)", value: "EB", bytes: 1024 ** 6, description: "ExbiByte", type: "binary" }
];

// 十进制单位 (1000进制)
const decimalUnits: Unit[] = [
  { label: "字节 (B)", value: "B_DEC", bytes: 1, description: "Byte", type: "decimal" },
  { label: "千字节 (kB)", value: "kB", bytes: 1000, description: "Kilobyte", type: "decimal" },
  { label: "兆字节 (MB)", value: "MB_DEC", bytes: 1000 ** 2, description: "Megabyte", type: "decimal" },
  { label: "吉字节 (GB)", value: "GB_DEC", bytes: 1000 ** 3, description: "Gigabyte", type: "decimal" },
  { label: "太字节 (TB)", value: "TB_DEC", bytes: 1000 ** 4, description: "Terabyte", type: "decimal" },
  { label: "拍字节 (PB)", value: "PB_DEC", bytes: 1000 ** 5, description: "Petabyte", type: "decimal" },
  { label: "艾字节 (EB)", value: "EB_DEC", bytes: 1000 ** 6, description: "Exabyte", type: "decimal" }
];

// 所有单位
const allUnits = computed(() => [...binaryUnits, ...decimalUnits]);

// 快捷预设
const quickPresets: QuickPreset[] = [
  { label: "1KB", value: 1, fromUnit: "KB", toUnit: "B" },
  { label: "1MB", value: 1, fromUnit: "MB", toUnit: "KB" },
  { label: "1GB", value: 1, fromUnit: "GB", toUnit: "MB" },
  { label: "4GB内存", value: 4, fromUnit: "GB", toUnit: "MB" },
  { label: "256GB硬盘", value: 256, fromUnit: "GB", toUnit: "MB" },
  { label: "1TB硬盘", value: 1, fromUnit: "TB", toUnit: "GB" }
];

// 表单数据
const form = reactive<FormState>({
  value: 1,
  fromUnit: "GB",
  toUnit: "MB"
});

// 转换结果
const result = ref("1024.00");
const precision = ref(2);

// 计算参数
const stepValue = computed(() => {
  const unit = getUnitInfo(form.fromUnit);
  return unit && unit.bytes >= 1024 ** 3 ? 0.1 : 1;
});

const maxValue = computed(() => {
  const unit = getUnitInfo(form.fromUnit);
  if (!unit) return Number.MAX_SAFE_INTEGER;
  // 根据单位设置合理的最大值
  if (unit.bytes >= 1024 ** 4) return 1000; // TB级别最大1000
  if (unit.bytes >= 1024 ** 3) return 10000; // GB级别最大10000
  return Number.MAX_SAFE_INTEGER;
});

// 获取单位信息
const getUnitInfo = (unitValue: string): Unit | undefined => {
  return allUnits.value.find(u => u.value === unitValue);
};

// 转换函数
const convert = (value: number, fromUnit: string, toUnit: string): number => {
  const fromUnitInfo = getUnitInfo(fromUnit);
  const toUnitInfo = getUnitInfo(toUnit);

  if (!fromUnitInfo || !toUnitInfo) {
    throw new Error("无效的单位");
  }

  // 先转换为字节，再转换为目标单位
  const bytes = value * fromUnitInfo.bytes;
  return bytes / toUnitInfo.bytes;
};

// 转换为指定单位
const convertToUnit = (targetUnit: string): number => {
  try {
    return convert(form.value, form.fromUnit, targetUnit);
  } catch {
    return 0;
  }
};

// 格式化数字显示
const formatNumber = (value: number): string => {
  if (isNaN(value) || !isFinite(value)) return "0";

  if (value === 0) return "0";

  // 对于非常大或非常小的数字，使用科学计数法
  if (value >= 1e12 || (value < 0.001 && value > 0)) {
    return value.toExponential(precision.value);
  }

  // 普通格式化
  return value.toLocaleString("zh-CN", {
    minimumFractionDigits: 0,
    maximumFractionDigits: precision.value
  });
};

// 处理转换
const handleConvert = () => {
  try {
    if (form.value === null || form.value === undefined) {
      result.value = "0";
      return;
    }

    const convertedValue = convert(form.value, form.fromUnit, form.toUnit);
    result.value = formatNumber(convertedValue);
  } catch (error) {
    console.error("转换错误:", error);
    result.value = "转换错误";
    ElMessage.error("转换失败，请检查输入参数");
  }
};

// 应用快捷预设
const applyPreset = (preset: QuickPreset) => {
  form.value = preset.value;
  form.fromUnit = preset.fromUnit;
  form.toUnit = preset.toUnit;
  handleConvert();
  ElMessage.success(`已应用预设：${preset.label}`);
};

// 复制结果
const copyResult = async () => {
  if (!result.value || result.value === "0") {
    ElMessage.warning("没有可复制的结果");
    return;
  }

  try {
    await navigator.clipboard.writeText(result.value);
    ElMessage.success("复制成功");
  } catch (error) {
    // 降级方案
    const textArea = document.createElement("textarea");
    textArea.value = result.value;
    document.body.appendChild(textArea);
    textArea.select();
    document.execCommand("copy");
    document.body.removeChild(textArea);
    ElMessage.success("复制成功");
  }
};

// 重置表单
const resetForm = () => {
  form.value = 1;
  form.fromUnit = "GB";
  form.toUnit = "MB";
  precision.value = 2;
  handleConvert();
  ElMessage.success("已重置");
};

// 初始转换
handleConvert();

interface DrawerProps {}

const drawerVisible = ref(false);
const drawerProps = ref<DrawerProps>({});

// 接收父组件传过来的参数
const acceptParams = async (params: DrawerProps) => {
  drawerProps.value = params;
  drawerVisible.value = true;
  // 重置表单
  resetForm();
};

defineExpose({
  acceptParams
});
</script>

<style lang="scss" scoped>
.byte-convert-form {
  display: flex;
  flex-direction: column;
  gap: 24px;
  .input-section,
  .result-section,
  .quick-actions {
    .section-title {
      display: flex;
      gap: 8px;
      align-items: center;
      margin: 0 0 16px;
      font-size: 16px;
      font-weight: 600;
      color: var(--el-text-color-primary);
      .el-icon {
        color: var(--el-color-primary);
      }
    }
  }
  .input-section {
    padding: 20px;
    background: var(--el-bg-color-page);
    border: 1px solid var(--el-border-color-lighter);
    border-radius: 8px;
  }
  .result-section {
    .result-display {
      margin-bottom: 16px;
      :deep(.el-input__inner) {
        font-size: 18px;
        font-weight: 600;
        color: var(--el-color-primary);
        text-align: center;
      }
    }
    .conversion-details {
      .details-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
        gap: 8px;
        margin-top: 16px;
        .detail-item {
          display: flex;
          justify-content: space-between;
          padding: 8px 12px;
          font-size: 13px;
          background: var(--el-fill-color-light);
          border-radius: 4px;
          .unit-label {
            color: var(--el-text-color-regular);
          }
          .unit-value {
            font-weight: 600;
            color: var(--el-text-color-primary);
          }
        }
      }
    }
  }
  .quick-actions {
    padding: 16px;
    background: var(--el-bg-color-page);
    border: 1px solid var(--el-border-color-lighter);
    border-radius: 8px;
    .quick-buttons {
      display: flex;
      flex-wrap: wrap;
      gap: 8px;
    }
  }
  .info-section {
    .info-list {
      padding-left: 20px;
      margin: 8px 0 0;
      li {
        margin-bottom: 4px;
        font-size: 13px;
        line-height: 1.5;
        strong {
          color: var(--el-color-primary);
        }
      }
    }
  }
}
.dialog-footer {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}

// 响应式设计
@media (width <= 768px) {
  .byte-convert-form {
    gap: 16px;
    .input-section {
      padding: 16px;
    }
    .result-section {
      .conversion-details {
        .details-grid {
          grid-template-columns: 1fr;
        }
      }
    }
    .quick-actions {
      .quick-buttons {
        .el-button {
          flex: 1;
          min-width: 0;
        }
      }
    }
  }
}
</style>
